RDS for OracleでOracle Schedulerのタイムゾーンを設定する
しばたです。
RDS for OracleでのOracle Schedulerの設定まわりについて調査する必要があり、その結果と設定変更手順についてこの場で軽く共有します。
RDS for Oracleのタイムゾーンについて
RDS for OracleにおけるタイムゾーンはデフォルトでUTCとなっています。
オプショングループからTimeZone
オプションを設定することで、RDSのホストレベルでタイムゾーンを変更しOracleにも反映させることができます。
ただし、Oracle Schedulerが内部で持つタイムゾーン設定はこのオプションの影響を受けずUTCのままです。
これが問題となる一番わかりやすい例は自動データベース・メンテナンス・タスクで、現在サポートされているOracleの一般的な構成であれば、
- 毎週月~金曜日の22:00開始 (4時間以内に完了)
- 毎週土、日曜日の06:00開始 (20時間以内に完了)
にデータベースに対して統計情報の収集などのタスクを実施します。
RDS for Oracleではこの時刻がUTCになるため、日本でRDS for Oracleを使う場合にこのままだと都合が悪い場合があるかと思います。
Oracle Schedulerのタイムゾーン変更
そこで最初にOracle Schedulerのタイムゾーンを変更します。
手順は以下のドキュメントにばっちり書いてあります。
RDS for Oracleでも通常のOracleと同様にDBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE
を使うことでOracle Schedulerのタイムゾーンを変更できます。
-- 現在のOracle Schedulerタイムゾーンを確認
SELECT VALUE FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE WHERE ATTRIBUTE_NAME='DEFAULT_TIMEZONE';
-- Oracle SchedulerのデフォルトタイムゾーンをAsia/Tokyo (+09:00) に変更
EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE('default_timezone','Asia/Tokyo');
-- 変更後のOracle Schedulerタイムゾーンを確認
SELECT VALUE FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE WHERE ATTRIBUTE_NAME='DEFAULT_TIMEZONE';
やってみた
今回TimeZone
オプションをAsia/Tokyo
にしたOracle 19c SE2(19.0.0.0.ru-2021-04.rur-2021-04.r1)環境を用意しました。
初期状態の時刻を確認してみると以下の様にSYSTIMESTAMP
はJSTの時刻を返しますがOracle SchedulerはUTCの時刻を返します。
各タスクの実行予定もUTCです。
ここでDBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE
を実行してやるとOracle Schedulerのデフォルトタイムゾーンおよび各タスクの実行予定時刻が無事Asia/Tokyo
に変更されました。
Oracle Schedulerタスクの時刻変更
先述の自動データベース・メンテナンス・タスクの実行時刻に対してタイムゾーンを変更するだけでなく、実行時刻やDuration自体を変えたい場合もあるでしょう。
その場合はDBMS_SCHEDULER
パッケージを使い、
- 当該スケジュールを一旦無効に
- 当該スケジュールの属性変更
- 当該スケジュールを有効に戻す
の手順を踏む必要があります。
実行例がOracleのドキュメントにありますので詳細はそちらをご覧ください。
やってみた
前節で紹介した環境を使い月曜日のメンテナンスタスク(SYS.MONDAY_WINDOW
)を変更する簡単な例を紹介します。
--
-- 月曜日のメンテナンスタスク(SYS.MONDAY_WINDOW)のスケジュールを変える例
--
DECLARE
V_WINDOW_NAME VARCHAR2(257) := 'SYS.MONDAY_WINDOW';
BEGIN
-- 設定変更前に無効に
DBMS_SCHEDULER.DISABLE(name => V_WINDOW_NAME);
-- スケジュールの属性変更 (実行間隔) : 通常月曜 22:00 開始を 03:00 開始に変更
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => V_WINDOW_NAME,
attribute => 'REPEAT_INTERVAL',
value => 'freq=daily;byday=MON;byhour=3;byminute=0;bysecond=0'
);
-- スケジュールの属性変更 (Duration) : 通常4時間のを2時間に変更
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => V_WINDOW_NAME,
attribute => 'DURATION',
value => NUMTODSINTERVAL(2, 'hour')
);
-- 設定変更後有効に
DBMS_SCHEDULER.ENABLE(name => V_WINDOW_NAME);
END;
/
月曜日の次回実行時刻が無事更新されました。
余談 : rdsadmin_util.alter_db_time_zone について
RDS for Oracleでタイムゾーンに関わる設定には最初に紹介したTimeZone
オプション以外にRDSの管理パッケージにあるrdsadmin_util.alter_db_time_zone
プロシージャも存在します。
rdsadmin_util.alter_db_time_zone
プロシージャはドキュメントに
alter_db_time_zone プロシージャは、特定のデータ型のみのタイムゾーンを変更し、SYSDATE は変更しません。タイムゾーンの設定に関する他の制限については、Oracle ドキュメントに示されています。
とある様に特定のデータ型向けの様でOracle Schedulerのタイムゾーンには影響を及ぼしませんでした。
調べてみたもののrdsadmin_util.alter_db_time_zone
プロシージャはDBTIMEZONE
を変更するのは確認できたのですが、それ以外にどこに影響するのかは正直わかりませんでした。
DBTIMEZONE
も原則変更するものではないですし、rdsadmin_util.alter_db_time_zone
プロシージャは本当に必要に迫られた場合以外は使わない方が良さそうに思えました。
最後に
以上となります。
今回はテスト環境で試してますので気軽にタイムゾーンやスケジュールを変えていますが、本番環境で実施する際は既存のタスクへの影響[1]を考慮し変更タイミングを念入りに調整する必要があるでしょう。
Oracleのタイムゾーン設定は地味に複雑で分かりにくいところがありますが、本記事の内容が役に立てば幸いです。
時刻変更により実行してほしいタスクがスキップされてしまわないか、など ↩︎